/**
 * Copyright c FOUNDER 2003 All Rights Reserved.
 * SqlList.java
 */
package com.iori.common.db.dbctrl;

import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.ResourceBundle;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.SAXException;

/**
 * [クラス名]<br>
 * SQLリストクラス<br>
 * <br>
 * [機能概要]<br>
 * SQLリストの設定と、SQL文を保持するクラス。<br>
 * <br>
 * [変更履歴]<br>
 * 2005/07/30 ver1.00 新規作成 zhanjc<br>
 * <br>
 *
 * @author zhanjc
 * @version 1.00
 */
public class SqlList {

	/**
	 * ログ出力用のインスタンス生成。
	 */
	protected static Log logger = LogFactory.getLog(SqlList.class);

	/**
	 * SQLファイルのパス
	 */
	private static String SQL_FILE_PATH = "sqllist.sql.path";

	/**
	 * SQLファイルのキーワード
	 */
	private static String SQL_FILE_BASE = "sqllist.sql.file.";

	/**
	 * sqllist設定
	 */
	private ResourceBundle sqlListConfig;

	/**
	 * SQL文のマップ
	 */
	protected Map sql;

	/**
	 * 初期化処理。（コンストラクタ）<br>
	 * sqllist.propertiesファイルより設定をロードし、 関連付けられたSQLファイルからSQL文を取得する。
	 *
	 * @param config
	 *            sqllist.propertiesファイル
	 *
	 * @exception IOException
	 *                ファイルロードエラー
	 */
	public SqlList(String config) {
		// SQLListファイルのロード成功時のみSQLファイルのロードを実行
		if (loadSqlListConfig(config)) {
			this.sql = new HashMap();
			String name = null, key = null, value = null;
			for (Enumeration enums = sqlListConfig.getKeys(); enums.hasMoreElements();) {
				name = (String) enums.nextElement();
				try {
					if (name.indexOf(SQL_FILE_BASE) == 0) {
						String sqlPath = sqlListConfig.getString(name);
						InputStream is = this.getClass().getClassLoader().getResourceAsStream(sqlPath);
						SqlFileLoader fileLoader = new SqlFileLoader();
						fileLoader.load(is);

						Iterator ite = fileLoader.keySet().iterator();
						// ストリーム内の全sql文を取得
						while (ite.hasNext()) {
							key = (String) ite.next();
							value = (String) fileLoader.get(key);
							this.sql.put(key, SqlRetouch.doRetouch(value));
							logger.debug("SQL BF:" + value);
							logger.debug("SQL AF:" + SqlRetouch.doRetouch(value));
						}
						is.close();
						// ロードに成功したSQLファイル名を表示
						logger.debug("SQL file '" + sqlPath + "'was loaded successfuly");
					}
				} catch (IOException e) {
					logger.error(e.getMessage());
				} catch (SAXException se) {
					logger.error(se.getMessage() + " (FileName=" + sqlListConfig.getString(name) + ")");
				}
			}
		} else {
			// SQLListファイルのロード失敗
			logger.error("SQLListファイルのロード失敗");
		}
	}

	/**
	 * SqlListクラスを破棄する。<br>
	 * サーブレットなど外部から呼び出されると、SqlListクラスが初期化前の状態に戻る。<br>
	 */
	public void destroy() {
		this.sqlListConfig = null;
		this.sql.clear();
	}

	/**
	 * 指定されたidにマップされたSQL文を取得する。
	 *
	 * @param id
	 *            SQL文のid
	 *
	 * @return PreparedSql 変換済みSQLクラス
	 */
	public PreparedSql getSql(String id) {
		Object obj = this.sql.get(id);
		if (obj != null) {
			SqlBrokenModel sql = (SqlBrokenModel) obj;
			return new PreparedSql(sql);
		} else {
			return null;
		}
	}

	/**
	 * SQLファイルのパスを取得する。
	 *
	 * @return バインド変数名のキーワード
	 */
	public String getSqlListPath() {
		return this.sqlListConfig.getString(SQL_FILE_PATH);
	}

	/**
	 * sqlListConfigをロードする。
	 *
	 * @param config
	 *            ロードするプロパティファイルのfile name
	 * @return ロード成功: true ロード失敗:false
	 */
	private boolean loadSqlListConfig(String config) {
		try {
			sqlListConfig = ResourceBundle.getBundle(config);
			return true;
		} catch (Exception e) {
			logger.error(e.getMessage());
			return false;
		}
	}

}
